package com.jindu.producer.system.controller;


import com.jindu.kernel.page.AlphaPage;
import com.jindu.kernel.result.JsonResult;
import com.jindu.kernel.result.StatusCode;
import com.jindu.kernel.utils.*;
import com.jindu.kernel.wxpay.Constant;
import com.jindu.producer.system.jpa.EmailVerificationJpa;
import com.jindu.producer.system.jpa.MobileVerificationJpa;
import com.jindu.producer.system.jpa.UserLogJpa;
import com.jindu.producer.system.jpa.UsersJpa;
import com.jindu.producer.system.shiro.JwtUtils;
import com.google.gson.Gson;
import com.jindu.producer.system.model.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.persistence.criteria.Predicate;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.List;


/**
 * @author jarvis
 * @date 2018/1/28
 */
@Api(description = "用户信息管理", tags = "UsersController", basePath = "/user")
@RestController
@RequestMapping(value = "/user",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class UsersController {

    Logger logger = LoggerFactory.getLogger(UsersController.class);

    /**
     * 正则表达式：必须是数字或字母,不能全是字母或数字，8-23 位长度限制。
     */
    String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,23}$";

    /**
     * 正则表达式：验证手机号
     */
    String REGEX_MOBILE = "^((1[0-9][0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";

    /**
     * 正则表达式：验证邮箱
     */
    String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

    @Autowired
    UsersJpa usersJpa;

    @Autowired
    MobileVerificationJpa mobileVerificationJpa;

    @Autowired
    EmailVerificationJpa emailVerificationJpa;

    @Autowired
    UserLogJpa userLogJpa;


    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token" , required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "根据用户ID，查询用户的详细信息", notes = "返回单个用户的信息,用户详细信息")
    @RequestMapping(value = "get",method = RequestMethod.GET)
    public JsonResult<SUsersEntity> get(@RequestParam(value = "id") String id){
        return JsonResult.getSuccessResult(usersJpa.findById(id));
    }

    @ApiOperation(value = "根据用户昵称，中文名，账户等，返回该用户的Id", notes = "用于进行用户模糊查询")
    @RequestMapping(value = "getUserIdByName",method = RequestMethod.GET)
    public List<String> getUserIdByName(@RequestParam String userName){
        List<SUsersEntity> entity=usersJpa.findByUserName(userName);
        List<String> list=new ArrayList<>();
        if(entity.size()>0){
            for (SUsersEntity u: entity) {
                list.add(u.getId());
            }
        }
        return list;
    }

    @RequestMapping(value = "getName",method = RequestMethod.GET)
    public  HashMap<String,String> getName(@RequestParam(value = "userName") String userName){
        List<String> userIds = new ArrayList<>();
        HashMap<String,String> account=new HashMap<>();
        String[] userId=userName.split(",");
        for (int i=0;i<userId.length;i++){
            userIds.add(userId[i]);
        }

        List<SUsersEntity> users=usersJpa.findByIdIn(userIds);
        for (SUsersEntity u: users) {
            account.put(u.getId(),u.getChineseName());
        }

        return account;
    }

    @ApiOperation(value = "根据用户id的集合，返回一组用户的中文名称的HashMap", notes = "返回用户姓名的hashMap信息,用于管理查询的userId换成姓名")
    @RequestMapping(value = "getUserName",method = RequestMethod.GET)
    public HashMap<String,String> getUserName(@RequestParam(value = "userIds") List<String> userIds){

        HashMap<String,String> userName=new HashMap<>();
        List<SUsersEntity> users=usersJpa.findByIdIn(userIds);
        for (SUsersEntity u: users) {
            userName.put(u.getId(),u.getChineseName());
        }
        return userName;
    }



    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token" , required = false, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "根据分页条件，查询用户的信息列表", notes = "返回用户的信息列表,可以账户模糊查询")
    @RequestMapping(value = "getAll", method = RequestMethod.GET)
    public JsonResult<AlphaPage<SUsersEntity>> findAll(@RequestParam(value = "pageNo",defaultValue = "0") Integer pageNo,
                                                       @RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,
                                                       @RequestParam(value = "account", required = false) String account,
                                                       @RequestParam(value = "status", required = false) Integer status){

        Specification querySpecifi = (Specification<SUsersEntity>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if(account != null){
                predicates.add(criteriaBuilder.like(root.get("account"),"%"+account+"%"));
            }
            if(status != null){
                predicates.add(criteriaBuilder.equal(root.get("status"),status));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<SUsersEntity> entities=usersJpa.findAll(querySpecifi,new PageRequest(pageNo, pageSize));
        return new AlphaPage<>(entities).toJsonResult();
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token" , required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "保存用户信息", notes = "保存用户信息")
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public JsonResult<SUsersEntity> save(@RequestBody SUsersEntity usersEntity){

        SUsersEntity sUsersEntity=usersJpa.findById(usersEntity.getId());
        if(sUsersEntity==null){
            usersEntity.setId(IdGenerator.uuid());
            usersEntity.setRegisterTime(new Timestamp(DateUtils.getCurrentTime()));
            usersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));
            if (StringUtils.isNotBlank(usersEntity.getPwd())) {
                usersEntity.setPwd(MD5Util.getMD5String(usersEntity.getPwd()));
            }
            return JsonResult.getSuccessResult(usersJpa.saveAndFlush(usersEntity));
        }else {
            usersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));
            BeanUtils.copyProperties(usersEntity,sUsersEntity, AlphaBeanUtils.getNullPropertyNames(usersEntity));
            return JsonResult.getSuccessResult(usersJpa.saveAndFlush(sUsersEntity));
        }
    }

    @ApiOperation(value = "管理后台登录", notes = "管理后台用户账户登录")
    @RequestMapping(value = "login", method = RequestMethod.GET)
    public JsonResult<HashMap<String,Object>> login(ServletRequest request,
                                                    @RequestParam("account") String account,
                                                    @RequestParam("pwd") String pwd) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HashMap<String,Object> user=new HashMap<>();
        SUserLogEntity logEntity=null;

        SUsersEntity result = usersJpa.findByAccount(account);
        if (result == null) {
            //记录日志,查不到用户账号
            buildUserLog(account,1,1,0,httpServletRequest,"未查到账号"+account);

            user.put("statusCode",StatusCode.NotFindAccount.getCode().toString());
            user.put("statusMessage",StatusCode.NotFindAccount.getMeaning());

            return JsonResult.getFailureResult(StatusCode.INVALID_REQUEST,user);
        }
        String encryptedPwd = MD5Util.getMD5String(pwd);
        if (!encryptedPwd.equalsIgnoreCase(result.getPwd())) {
            //记录日志,密码错误
            buildUserLog(account,1,1,0,httpServletRequest,"密码错误");

            user.put("statusCode",StatusCode.PassWordError.getCode().toString());
            user.put("statusMessage",StatusCode.PassWordError.getMeaning());

            return JsonResult.getFailureResult(StatusCode.INVALID_REQUEST,user);
        }

        String token = JwtUtils.sign(account,result.getId());
        user.put("token",token);
        user.put("id",result.getId());
        user.put("account",result.getAccount());
        user.put("chineseName",result.getChineseName());
        user.put("imageUrl",result.getImageUrl());

       buildUserLog(account,1,1,1,httpServletRequest,"后台登录成功");

        return JsonResult.getSuccessResult(user);
    }

    @ApiOperation(value = "用户中心登录", notes = "用户中心登录，可使用账户，邮件地址，手机号进行登录")
    @RequestMapping(value = "loginWeb", method = RequestMethod.GET)
    public JsonResult<HashMap<String,Object>> loginWeb(ServletRequest request,
                                                       @RequestParam("account") String account,
                                                       @RequestParam("pwd") String pwd){
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HashMap<String,Object> user=new HashMap<>();
        SUsersEntity result = usersJpa.findByAccountOrMobileOrEmail(account);
        SUserLogEntity logEntity=null;
        //未找到登录账户
        if (result == null) {
            buildUserLog(account,2,1,0,httpServletRequest,"账户名不正确，未找到账户");

            user.put("statusCode",StatusCode.NotFindAccount.getCode().toString());
            user.put("statusMessage",StatusCode.NotFindAccount.getMeaning());
            return JsonResult.getFailureResult(StatusCode.INVALID_REQUEST,user);
        }
        String encryptedPwd = MD5Util.getMD5String(pwd);
        //登录账户的密码不正确
        if (!encryptedPwd.equalsIgnoreCase(result.getPwd())) {
            buildUserLog(account,2,1,0,httpServletRequest,"登录账户的密码不正确");

            user.put("statusCode",StatusCode.PassWordError.getCode().toString());
            user.put("statusMessage",StatusCode.PassWordError.getMeaning());

            return JsonResult.getFailureResult(StatusCode.INVALID_REQUEST,user);
        }
        //账户未激活
        if (result.getStatus()!= 1) {
            //记录日志
            buildUserLog(account,2,1,0,httpServletRequest,"账户未激活");

            user.put("statusCode",StatusCode.AccountUnActive.getCode().toString());
            user.put("statusMessage",StatusCode.AccountUnActive.getMeaning());

            return JsonResult.getFailureResult(StatusCode.INVALID_REQUEST,user);
        }

        String token = JwtUtils.sign(account,result.getId());

        user.put("token",token);
        user.put("id",result.getId());
        user.put("account",result.getAccount());
        user.put("chineseName",result.getChineseName());
        user.put("imageUrl",result.getImageUrl());

        buildUserLog(account,2,1,1,httpServletRequest,"web端登录成功");

        return JsonResult.getSuccessResult(user);

    }

    @ApiOperation(value = "【小程序】微信小程序登录和授权", notes = "用于微信小程序的登录")
    @RequestMapping(value = "loginMiniApp", method = RequestMethod.GET)
    public JsonResult<HashMap<String,Object>> loginMiniApp(ServletRequest request,
                                                           @RequestParam("code") String code){
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HashMap<String,Object> user=new HashMap<>();

        String APPID = Constant.APP_ID;
        String SECRET = Constant.APP_SECRET;

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+APPID+"&secret="+SECRET+"&js_code="+ code +"&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        //进行网络请求,访问url接口
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        //根据返回值进行后续操作
        if(responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK)
        {
            String sessionData = responseEntity.getBody();
            Gson gson = new Gson();

            //解析从微信服务器获得的openid和session_key;
            WeChatSession weChatSession = gson.fromJson(sessionData,WeChatSession.class);
            //获取用户的唯一标识
            String openid = weChatSession.getOpenid();
            //获取会话秘钥
            String session_key = weChatSession.getSession_key();
            //下面就可以写自己的业务代码了
            logger.warn("openid：",openid);
            logger.warn("session_key：",session_key);
            //最后要返回一个自定义的登录态,用来做后续数据传输的验证

            SUsersEntity sUsersEntity=getUserByOpenId(openid);
            buildUserLog(sUsersEntity.getAccount(),2,1,1,httpServletRequest,"小程序登录成功");

            String token = JwtUtils.sign(sUsersEntity.getAccount(),sUsersEntity.getId());
            user.put("token",token);
            user.put("id",sUsersEntity.getId());
            user.put("account",sUsersEntity.getAccount());
            user.put("nickname",sUsersEntity.getNickname());
            user.put("imageUrl",sUsersEntity.getImageUrl());
            user.put("openId",sUsersEntity.getOpenId());
        }

        return JsonResult.getSuccessResult(user);

    }
    @ApiOperation(value = "【小程序】微信小程序登录和授权", notes = "用于微信小程序的登录，jarvis的微信")
    @RequestMapping(value = "loginMiniApp2", method = RequestMethod.GET)
    public JsonResult<HashMap<String,Object>> loginMiniApp2(ServletRequest request,
                                                           @RequestParam("code") String code){
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HashMap<String,Object> user=new HashMap<>();

        String APPID = Constant.APP_ID2;
        String SECRET = Constant.APP_SECRET2;

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+APPID+"&secret="+SECRET+"&js_code="+ code +"&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        //进行网络请求,访问url接口
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        //根据返回值进行后续操作
        if(responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK)
        {
            String sessionData = responseEntity.getBody();
            Gson gson = new Gson();

            //解析从微信服务器获得的openid和session_key;
            WeChatSession weChatSession = gson.fromJson(sessionData,WeChatSession.class);
            //获取用户的唯一标识
            String openid = weChatSession.getOpenid();
            //获取会话秘钥
            String session_key = weChatSession.getSession_key();
            //下面就可以写自己的业务代码了
            logger.warn("openid：",openid);
            logger.warn("session_key：",session_key);
            //最后要返回一个自定义的登录态,用来做后续数据传输的验证

            SUsersEntity sUsersEntity=getUserByOpenId(openid);
            buildUserLog(sUsersEntity.getAccount(),2,1,1,httpServletRequest,"小程序登录成功");

            String token = JwtUtils.sign(sUsersEntity.getAccount(),sUsersEntity.getId());
            user.put("token",token);
            user.put("id",sUsersEntity.getId());
            user.put("account",sUsersEntity.getAccount());
            user.put("nickname",sUsersEntity.getNickname());
            user.put("imageUrl",sUsersEntity.getImageUrl());
            user.put("openId",sUsersEntity.getOpenId());
        }

        return JsonResult.getSuccessResult(user);

    }

    @ApiOperation(value = "【小程序】微信小程序获取用户信息后，存数据库", notes = "用于微信小程序的用户信息保存")
    @RequestMapping(value = "getWeChatUserInfo", method = RequestMethod.POST)
    public JsonResult<SUsersEntity> getWeChatUserInfo(@RequestParam("id") String id,
                                                      @RequestParam("nickname") String nickname,
                                                      @RequestParam("sex") String sex,
                                                      @RequestParam("imageUrl") String imageUrl){

        SUsersEntity sUsersEntity=usersJpa.findById(id);
        if(sUsersEntity!=null){
            sUsersEntity.setNickname(nickname);
            sUsersEntity.setSex(sex);
            sUsersEntity.setImageUrl(imageUrl);
            sUsersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));
        }
        return JsonResult.getSuccessResult(usersJpa.saveAndFlush(sUsersEntity));
    }


    public SUsersEntity getUserByOpenId(String openId){

        SUsersEntity sUsersEntity=usersJpa.findByOpenId(openId);
        if(sUsersEntity==null){
            SUsersEntity usersEntity=new SUsersEntity();

            usersEntity.setId(IdGenerator.uuid());
            Integer randomAccount= RandomUtil.getNum(100000,999999);
            usersEntity.setAccount(randomAccount.toString());
            usersEntity.setOpenId(openId);
            usersEntity.setStatus(1);
            usersEntity.setRegisterTime(new Timestamp(DateUtils.getCurrentTime()));
            usersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));
            return usersJpa.saveAndFlush(usersEntity);
        }else {
            return sUsersEntity;
        }

    }


    /**
     *
     * @param account 访问的账户
     * @param plat 登录的入口 后台，web，移动端
     * @param type 登录，退出，访问码
     * @param flag 是否成功
     * @param httpServletRequest 请求的httpRequest
     * @return
     */
    public SUserLogEntity buildUserLog(String account,int plat,int type,int flag, HttpServletRequest httpServletRequest,String operation){
        SUserLogEntity userLogEntity=new SUserLogEntity();
        userLogEntity.setId(IdGenerator.uuid());
        userLogEntity.setAccount(account);
        userLogEntity.setLoginPlatform(plat);
        userLogEntity.setType(type);
        userLogEntity.setOperation(operation);
        userLogEntity.setUserIp(IpAddressUtil.getIpAdrress(httpServletRequest));
        userLogEntity.setSuccessFlag(flag);
        userLogEntity.setLogTime(new Timestamp(DateUtils.getCurrentTime()));

        return userLogJpa.saveAndFlush(userLogEntity);
    }

    @ApiOperation(value = "用户mobile注册", notes = "用户mobile注册")
    @RequestMapping(value = "registerByMobileWithCode", method = RequestMethod.POST)
    public JsonResult<HashMap<String,Object>> registerByMobileWithCode(@RequestParam("mobile") String mobile,
                                                               @RequestParam("pwd") String pwd,
                                                               @RequestParam("code") Integer code){
        Timestamp time=new Timestamp(DateUtils.getCurrentTime());
        HashMap<String,Object> codeMessage=new HashMap<>();

        SUsersEntity usersEntity=usersJpa.findByMobile(mobile);

        //账户已存在
        if(usersEntity!=null){

            codeMessage.put("statusCode",StatusCode.AccountAlreadyExists.getCode().toString());
            codeMessage.put("statusMessage",StatusCode.AccountAlreadyExists.getMeaning());

            return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
        }
        //根据手机号，查询最后一条有效的验证码
        SMobileVerificationEntity entity= validVerificationCodeByMobile(mobile);
        if(entity!=null){
            //设定时间为15分钟有效期
            Timestamp timeBegin=new Timestamp(entity.getCreateTime().getTime()+15*60*1000);

            if(entity.getVerification()!=code){
                //验证码错误
                codeMessage.put("statusCode",StatusCode.VerificationCodeError.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.VerificationCodeError.getMeaning());

                return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
            }
            if(timeBegin.before(time)){
                //验证码已过期
                codeMessage.put("statusCode",StatusCode.VerificationCodeExpired.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.VerificationCodeExpired.getMeaning());
                return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
            }
            if(pwd.matches(regex)){
                SUsersEntity sUsersEntity=new SUsersEntity();
                sUsersEntity.setId(IdGenerator.uuid());
                sUsersEntity.setPwd(MD5Util.getMD5String(pwd));
                sUsersEntity.setMobile(mobile);
                sUsersEntity.setStatus(1);
                sUsersEntity.setLoginType(2);
                sUsersEntity.setSkin("1");

                sUsersEntity.setRegisterTime(new Timestamp(DateUtils.getCurrentTime()));
                sUsersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));

                usersJpa.saveAndFlush(sUsersEntity);
                //创建用户成功
                codeMessage.put("statusCode",StatusCode.CREATED.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.CREATED.getMeaning());

                return JsonResult.getSuccessResult(codeMessage);
            }
            else {
                //密码不符合规则
                codeMessage.put("statusCode",StatusCode.PasswordRule.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.PasswordRule.getMeaning());
                return JsonResult.getSuccessResult(codeMessage);
            }
        }
        else {
            //未找到该手机号的验证码
            codeMessage.put("statusCode",StatusCode.NotFindVerificationCode.getCode().toString());
            codeMessage.put("statusMessage",StatusCode.NotFindVerificationCode.getMeaning());

            return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
        }
    }

    @ApiOperation(value = "用户mobile注册", notes = "用户mobile注册")
    @RequestMapping(value = "registerByMobile", method = RequestMethod.POST)
    public JsonResult<HashMap<String,Object>> registerByMobile(@RequestParam("mobile") String mobile,
                                                               @RequestParam("pwd") String pwd){
        Timestamp time=new Timestamp(DateUtils.getCurrentTime());
        HashMap<String,Object> codeMessage=new HashMap<>();
        SUsersEntity usersEntity=usersJpa.findByMobile(mobile);
        //账户已存在
        if(usersEntity!=null){
            codeMessage.put("statusCode",StatusCode.AccountAlreadyExists.getCode().toString());
            codeMessage.put("statusMessage",StatusCode.AccountAlreadyExists.getMeaning());
            return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
        }else {
            if(pwd.matches(regex)){
                SUsersEntity sUsersEntity=new SUsersEntity();
                sUsersEntity.setId(IdGenerator.uuid());
                sUsersEntity.setPwd(MD5Util.getMD5String(pwd));
                sUsersEntity.setMobile(mobile);
                sUsersEntity.setAccount(mobile);
                sUsersEntity.setNickname(mobile);
                sUsersEntity.setStatus(1);
                sUsersEntity.setLoginType(2);
                sUsersEntity.setSkin("1");

                sUsersEntity.setRegisterTime(new Timestamp(DateUtils.getCurrentTime()));
                sUsersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));

                usersJpa.saveAndFlush(sUsersEntity);
                //创建用户成功
                codeMessage.put("statusCode",StatusCode.CREATED.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.CREATED.getMeaning());
                return JsonResult.getSuccessResult(codeMessage);
            }
            else {
                //密码不符合规则
                codeMessage.put("statusCode",StatusCode.PasswordRule.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.PasswordRule.getMeaning());
                return JsonResult.getSuccessResult(codeMessage);
            }
        }
    }
    /**
     * 验证码有效性验证, 根据参数,去查询数据数据库中是否有对应的记录
     * @param mobile
     * @return
     */
    public SMobileVerificationEntity validVerificationCodeByMobile(String mobile){

        Specification querySpecifi = (Specification<SMobileVerificationEntity>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.equal(root.get("mobile"),mobile));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        List<SMobileVerificationEntity> entitys= mobileVerificationJpa.findAll(querySpecifi,sort);
        return entitys.size()>0? entitys.get(0):null;
    }

    @ApiOperation(value = "用户中心Email注册", notes = "用户中心Email注册")
    @RequestMapping(value = "registerByEmail", method = RequestMethod.POST)
    public JsonResult<HashMap<String,Object>> registerByEmail(@RequestParam("email") String email,
                                                            @RequestParam("pwd") String pwd,
                                                            @RequestParam("code") Integer code){
        Timestamp time=new Timestamp(DateUtils.getCurrentTime());
        HashMap<String,Object> codeMessage=new HashMap<>();
        SUsersEntity usersEntity=usersJpa.findByEmail(email);
        //账户已存在
        if(usersEntity!=null){

            codeMessage.put("statusCode",StatusCode.AccountAlreadyExists.getCode().toString());
            codeMessage.put("statusMessage",StatusCode.AccountAlreadyExists.getMeaning());

            return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
        }
        //根据 邮件地址，获取最近的一个验证码
        SEmailVerificationEntity entity= validVerificationCodeByEmail(email);
        if(entity!=null)
        {
            //设定时间为10分钟有效期
            Timestamp timeBegin=new Timestamp(entity.getCreateTime().getTime()+15*60*1000);
            if(code!=Integer.parseInt(entity.getVerification())){
                //验证码错误
                codeMessage.put("statusCode",StatusCode.VerificationCodeError.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.VerificationCodeError.getMeaning());

                return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
            }
            if(timeBegin.before(time)){
                //验证码已过期
                codeMessage.put("statusCode",StatusCode.VerificationCodeExpired.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.VerificationCodeExpired.getMeaning());

                return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
            }

            if(pwd.matches(regex)) {
                SUsersEntity sUsersEntity = new SUsersEntity();
                sUsersEntity.setId(IdGenerator.uuid());
                sUsersEntity.setEmail(email);
                sUsersEntity.setPwd(MD5Util.getMD5String(pwd));
                sUsersEntity.setLastDate(new Timestamp(DateUtils.getCurrentTime()));

                sUsersEntity.setStatus(1);
                sUsersEntity.setLoginType(2);
                sUsersEntity.setSkin("1");

                sUsersEntity.setRegisterTime(new Timestamp(DateUtils.getCurrentTime()));
                sUsersEntity.setModifyTime(new Timestamp(DateUtils.getCurrentTime()));

                usersJpa.saveAndFlush(sUsersEntity);
                //创建用户
                codeMessage.put("statusCode",StatusCode.CREATED.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.CREATED.getMeaning());

                return JsonResult.getSuccessResult(codeMessage);
            }else {
                //密码不符合规则
                codeMessage.put("statusCode",StatusCode.PasswordRule.getCode().toString());
                codeMessage.put("statusMessage",StatusCode.PasswordRule.getMeaning());

                return JsonResult.getSuccessResult(codeMessage);
            }
        }else {
            //未找到该账户的验证码
            codeMessage.put("statusCode",StatusCode.NotFindVerificationCode.getCode().toString());
            codeMessage.put("statusMessage",StatusCode.NotFindVerificationCode.getMeaning());
            return JsonResult.getResult(StatusCode.INVALID_REQUEST,codeMessage);
        }
    }

    /**
     * 验证码有效性验证, 根据参数,去查询数据数据库中是否有对应的记录
     * @param email
     * @return
     */
    public SEmailVerificationEntity validVerificationCodeByEmail(String email){

        Specification querySpecifi = (Specification<SEmailVerificationEntity>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.equal(root.get("email"),email));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        List<SEmailVerificationEntity> entitys= emailVerificationJpa.findAll(querySpecifi,sort);
        return entitys.size()>0? entitys.get(0):null;
    }

}
